import * as Cesium from 'cesium';

/**
 * 自定义 Primitive 类，继承自 Cesium.Primitive
 * 支持逐帧更新功能
 */
class CustomPrimitive {
  constructor(options = {}) {
    this.show = Cesium.defaultValue(options.show, true);
    this.allowPicking = Cesium.defaultValue(options.allowPicking, true);

    // 自定义属性
    this._ready = false;
    this._commands = [];
    this._geometry = options.geometry;
    this._appearance = options.appearance;
    this._modelMatrix = Cesium.defaultValue(options.modelMatrix, Cesium.Matrix4.IDENTITY);
    this._id = options.id;

    // 动画相关属性
    this._startTime = performance.now();
    this._lastUpdateTime = 0;
    this._frameCount = 0;

    // 用户自定义的更新回调函数
    this._onUpdate = options.onUpdate;

    // 初始化
    this._initialize();
  }

  /**
   * 初始化方法
   * @private
   */
  _initialize () {
    if (this._geometry && this._appearance) {
      this._createCommands();
      this._ready = true;
    }
  }

  /**
   * 创建渲染命令
   * @private
   */
  _createCommands () {
    if (!this._geometry || !this._appearance) {
      return;
    }

    // 创建顶点数组
    const vertexArray = Cesium.VertexArray.fromGeometry({
      context: this._context,
      geometry: this._geometry,
      attributeLocations: this._appearance._attributeLocations,
      bufferUsage: Cesium.BufferUsage.STATIC_DRAW,
    });

    // 创建着色器程序
    const shaderProgram = Cesium.ShaderProgram.fromCache({
      context: this._context,
      vertexShaderSource: this._appearance.vertexShaderSource,
      fragmentShaderSource: this._appearance.fragmentShaderSource,
      attributeLocations: this._appearance._attributeLocations,
    });

    // 创建渲染状态
    const renderState = Cesium.RenderState.fromCache({
      depthTest: {
        enabled: true,
        func: Cesium.DepthFunction.LESS,
      },
      depthMask: true,
    });

    // 创建绘制命令
    const command = new Cesium.DrawCommand({
      vertexArray: vertexArray,
      primitiveType: this._geometry.primitiveType,
      renderState: renderState,
      shaderProgram: shaderProgram,
      uniformMap: this._appearance.uniforms,
      owner: this,
      modelMatrix: this._modelMatrix,
    });

    this._commands.push(command);
  }

  /**
   * 更新方法 - 每帧调用
   * @param {Cesium.FrameState} frameState 帧状态
   */
  update (frameState) {
    if (!this.show) {
      return;
    }

    // 更新时间信息
    const currentTime = performance.now();
    const deltaTime = currentTime - this._lastUpdateTime;
    this._lastUpdateTime = currentTime;
    this._frameCount++;

    // 计算动画时间
    const animationTime = (currentTime - this._startTime) / 1000.0; // 转换为秒

    // 如果未准备好，尝试初始化
    if (!this._ready) {
      this._context = frameState.context;
      this._initialize();

      if (!this._ready) {
        return;
      }
    }

    // 更新模型矩阵（示例：旋转动画）
    this._updateModelMatrix(animationTime);

    // 更新外观和uniforms
    this._updateAppearance(frameState, animationTime, deltaTime);

    // 调用用户自定义的更新回调
    if (this._onUpdate) {
      this._onUpdate.call(this, frameState, animationTime, deltaTime, this._frameCount);
    }

    // 更新命令的模型矩阵
    for (let i = 0; i < this._commands.length; i++) {
      this._commands[i].modelMatrix = this._modelMatrix;
    }

    // 将命令添加到帧状态中进行渲染
    const passes = frameState.passes;
    if (passes.render || passes.pick) {
      for (let i = 0; i < this._commands.length; i++) {
        if (passes.render) {
          frameState.commandList.push(this._commands[i]);
        }
        if (passes.pick && this.allowPicking) {
          frameState.commandList.push(this._commands[i]);
        }
      }
    }
  }

  /**
   * 更新模型矩阵
   * @param {Number} animationTime 动画时间（秒）
   * @private
   */
  _updateModelMatrix (animationTime) {
    // 示例：创建旋转动画
    const rotation = animationTime * 0.5; // 每秒旋转0.5弧度

    this._modelMatrix = Cesium.Matrix4.multiply(
      Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, 0, 0)),
      Cesium.Matrix4.fromRotationZ(rotation),
      new Cesium.Matrix4()
    );
  }

  /**
   * 更新外观和uniforms
   * @param {Cesium.FrameState} frameState 帧状态
   * @param {Number} animationTime 动画时间
   * @param {Number} deltaTime 时间差
   * @private
   */
  _updateAppearance (frameState, animationTime, deltaTime) {
    if (!this._appearance) {
      return;
    }

    // 更新uniforms（示例）
    if (this._appearance.uniforms) {
      // 传递时间信息到着色器
      this._appearance.uniforms.u_time = function () {
        return animationTime;
      };

      this._appearance.uniforms.u_deltaTime = function () {
        return deltaTime / 1000.0; // 转换为秒
      };

      this._appearance.uniforms.u_frameCount = () => {
        return this._frameCount;
      };
    }
  }

  /**
   * 销毁资源
   */
  destroy () {
    // 清理渲染命令
    for (let i = 0; i < this._commands.length; i++) {
      const command = this._commands[i];
      command.vertexArray = command.vertexArray && command.vertexArray.destroy();
      command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy();
    }
    this._commands.length = 0;

    // 清理几何体和外观
    this._geometry = this._geometry && this._geometry.destroy();
    this._appearance = this._appearance && this._appearance.destroy();

    return Cesium.destroyObject(this);
  }

  /**
   * 检查对象是否已被销毁
   */
  isDestroyed () {
    return false;
  }

  /**
   * 设置新的几何体
   * @param {Cesium.Geometry} geometry 新的几何体
   */
  setGeometry (geometry) {
    this._geometry = geometry;
    this._ready = false;

    // 清理旧的命令
    this._commands.length = 0;
  }

  /**
   * 设置新的外观
   * @param {Cesium.Appearance} appearance 新的外观
   */
  setAppearance (appearance) {
    this._appearance = appearance;
    this._ready = false;

    // 清理旧的命令
    this._commands.length = 0;
  }

  /**
   * 设置用户更新回调
   * @param {Function} callback 回调函数
   */
  setUpdateCallback (callback) {
    this._onUpdate = callback;
  }

  /**
   * 获取动画时间
   * @returns {Number} 动画时间（秒）
   */
  getAnimationTime () {
    return (performance.now() - this._startTime) / 1000.0;
  }

  /**
   * 重置动画时间
   */
  resetAnimationTime () {
    this._startTime = performance.now();
    this._frameCount = 0;
  }
}

// 导出类
export default CustomPrimitive;
